home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol174 / crc65.asm < prev    next >
Encoding:
Assembly Source File  |  1986-11-25  |  32.0 KB  |  1,550 lines

  1. TITLE        'CRC.ASM Version 6.5 for MSDOS'
  2. ;               by Howard Vigorita, NYACC CP/M SIG
  3. ;    upload comments, etc. to: (718) 539-3338  (BBS)
  4. ;
  5. ;    A file CRC checking and generating utility for CP/M-86,
  6. ;    MP/M-86 and Concurrent PCDOS, now available for MSDOS.
  7. ;
  8. ;    Derived from the Bill Bolton's CP/M 86 version.
  9. ;
  10. ;    This is a companion utility to CRCBUILD which creates
  11. ;-CATALOG files. This utility uses the -CATALOG file as an
  12. ;interactive look up table and displays *MATCH* on your screen 
  13. ;next to each line whose embedded CRC agrees with disk contents.
  14. ;
  15. ;    This utility will optionally create an output file on 
  16. ;the default drive, listing the CRC's of all files checked in a
  17. ;single session. 
  18. ;
  19. ;
  20. ;COMMANDS:
  21. ;
  22. ;        CRC [drive:]<filename.filetype> [F]
  23. ;
  24. ;        Examples:
  25. ;
  26. ;    CRC            Will attempt to find CRCKLIST.???,
  27. ;                  or CRCKFILE.??? or -CATALOG.???    
  28. ;                  and try to match recorded CRC values
  29. ;                  in that file with values calculated
  30. ;                  on the fly for files on the disk. 
  31. ;
  32. ;    CRC MYFILE.ASM        Check only MYFILE.ASM
  33. ;
  34. ;    CRC B:*.ASM        Check all .ASM files ON B: drive
  35. ;
  36. ;    CRC *.* F        Check all files, writing output to a file
  37. ;
  38. ;
  39. ;
  40. ;SPECIAL MSDOS NOTE
  41. ;
  42. ;    This CRCK version fixes a bug in some MSDOS versions whereby
  43. ;partial sectors of files were not being processed. Such versions
  44. ;generate "00 00" CRC values for files less than 128 bytes in length
  45. ;and incorrect values for files not an exact multiple of 128 bytes
  46. ;long. Use this version of CRC with CRCBUILD version 1.1 which
  47. ;also fixes this bug.
  48. ;
  49. ;
  50. ;The CYCLIC-REDUNDANCY-CHECK number used is based on the
  51. ;CCITT standard polynominal:
  52. ;
  53. ;   X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
  54. ;
  55. ;Useful for checking accuracy of file transfers.
  56. ;More accurate than a simple checksum.
  57. ;
  58. ;
  59. ;CREDITS
  60. ;
  61. ;    The 8 bit version of the program was originally
  62. ;    conceived by Keith Petersen, W8SDZ, to whom all
  63. ;    glory and honour.
  64. ;
  65. ;
  66. ;VERSION LIST, most recent version first
  67. ;
  68. ;03/Nov/85 Altered buffer scheme to accept any size buffer.
  69. ;          CRC algorithm further optimized. Fixed bug in
  70. ;          version 6.4 whereby files between 65409 and 65535
  71. ;          bytes long yielded 00 00 CRC values.
  72. ;          Up to 600% faster than when 128 byte buffer used.
  73. ;          MSDOS version 6.5, Howard Vigorita 
  74. ;
  75. ;30/Oct/85 High speed version using 32K buffer on the file being CRC'd. 
  76. ;          Buffer size variable but must devide evenly into 64K. 
  77. ;          Up to 500% faster than when 128 byte buffer used.
  78. ;          CRC algorithm optimized.
  79. ;          MSDOS version 6.4, Howard Vigorita 
  80. ;
  81. ;20/Oct/85 Converted to MSDOS for assembly by MASM
  82. ;          MSDOS version 6.3, Howard Vigorita 
  83. ;
  84. ;30/Oct/84 Added CLOSE to file read routines, as Concurrent DOS
  85. ;          was reporting "Too many Files Open" error when CRCing
  86. ;       disks with lots of directory entries. Made the same
  87. ;       changes to the 8 bit versions.
  88. ;       CP/M-86/Concurrent version 6.4. Bill Bolton
  89. ;    
  90. ;10/Oct/84 Fixed CP/M-86 version to also work with Concurrent PCDOS,
  91. ;       and MP/M-86. The "?" in the OPEN function calls was
  92. ;       upsetting them. CP/M-86/Concurrent version 6.3. Bill Bolton
  93. ;
  94. ;09/Oct/84 XLT86 translation of 8 bit source code version, massaged
  95. ;       by hand to make it assemble with ASM86 for CP/M-86.
  96. ;          CP/M-86 version 6.2. Bill Bolton
  97. ;
  98. ;07/Oct/84 Tightened 8 bit disassembly considerably and moved all
  99. ;       the data together preparatory to XLT86ing for CP/M-86.
  100. ;       CP/M-80 version 6.2. Bill Bolton
  101. ;
  102. ;04/Oct/84 Disassembled CRC version 5.0 as distributed for some years
  103. ;       on SIG/M disks, but no source has even been available from
  104. ;       SIG/M. This version checks the -CATALOG files built with
  105. ;       CRCBUILD as well as CRCKLIST and CRCKFILE. Obviously used
  106. ;       SEQIO macros for much of the file I/O but as the aim is
  107. ;       translation to CP/M-86 I left the macros expanded. Lifted
  108. ;       recognisable bits of code (like MFNAME) from other sources
  109. ;       to get comments. Version number 6.1. 
  110. ;       Bill Bolton, Software Tools RCPM, Brisbane Australia
  111. ;
  112. ;-------------------------------------------------------------------
  113.  
  114.     ;    conditional assembly switches
  115.     ;    -----------------------------
  116. true        equ    0FFh
  117. false        equ    0
  118.  
  119.     ; switch to supress "no parse" error messages
  120.     ; set to 'false' to prevent screen clutter when using 
  121.     ; a -CATALOG file with a multi-line footer
  122.     ; 
  123. no_parse_msg    equ    false
  124.  
  125.     ;    equates
  126.     ;    -------
  127. dos    equ    33        ; MSDOS entry point
  128.  
  129. rdcon    equ    1        ; console input
  130. wrcon    equ    2        ; console output
  131. dircon    equ    6        ; direct console I/O
  132. print    equ    9        ; display string
  133. cstat    equ    11        ; console status
  134. open    equ    15        ; file open
  135. close    equ    16        ; file close
  136. srchf    equ    17        ; search for first
  137. srchn    equ    18        ; search for next
  138. delete    equ    19        ; delete file
  139. read    equ    20        ; read file
  140. write    equ    21        ; write file
  141. make    equ    22        ; create file
  142. rename    equ    23        ; rename existing file
  143. setdta    equ    26        ; set transfer address
  144. setiv    equ    25h        ; set interrupt vector
  145. makstr    equ    3Ch        ; make stream handle
  146. opnstr    equ    3Dh        ; open a file stream
  147. clostr    equ    3Eh        ; close file stream
  148. redstr    equ    3Fh        ; read from a stream
  149. wrtstr    equ    40h        ; write to a stream
  150. deldir    equ    41h        ; delete a directory entry
  151. trmproc    equ    4Ch        ; terminate process
  152.  
  153. tab    equ    09H        ;ASCII modulo 8 tab
  154. lf    equ    0AH        ;ASCII line feed
  155. cr    equ    0DH        ;ASCII carriage returnq
  156. eof    equ    1AH        ;CP/M end of file marker
  157.  
  158. bufsize    equ    80H        ;File buffers
  159. bufsizl    equ    200h        ; large file buffer
  160. dtamax    equ    1024*54        ; max size of dynamic dta
  161.  
  162. secsizs    equ    128        ; disk sector size
  163.  
  164. ; base page program segment prefix
  165. ; --------------------------------
  166. ;
  167. basepg    SEGMENT    AT 0
  168.  
  169.     ; base page file control block
  170.     ;
  171.     ORG    5Ch
  172. dfcb    db    12 dup (?)
  173. dfcbext    db    4 dup (?)
  174. dfcb2    db    16 dup (?)
  175. dfcbrno db    (?)
  176.  
  177.     ; default disk transfer area
  178.     ;
  179.     ORG    80h
  180. ddta    db    128 dup (?)
  181.  
  182. basepg    ENDS
  183.  
  184.  
  185.  
  186. ; program data storage area
  187. ; -------------------------
  188. ;
  189. data    SEGMENT PARA MEMORY
  190.  
  191.  
  192. FIRST_TRY    db    'CRCKFILE???',0
  193.  
  194. SIGNON        db    'MSDOS high speed CRC Ver 6.5, 3/Nov/85, Howard Vigorita',cr,lf
  195.         db    'CTL-S pauses, CTL-C aborts',cr,lf,cr,lf,0
  196.  
  197. SRCH_LIST    db    'Searching for "CRCKLIST" file    ',0
  198.  
  199. SRCH_FILE    db    'Now searching for "CRCKFILE" file',0
  200.  
  201. SRCH_CAT    db    'Now searching for "-CATALOG" file',0
  202.  
  203. NOFILECRC    db    tab
  204.         db    'Not found$'
  205.  
  206. CHECKING    db    tab,'Checking with file: ',0
  207.  
  208. NOFIND        db    '*No CRC Files found*',0
  209.  
  210. CANTPARSE    db    'Can not parse string',cr,lf,0
  211.  
  212. DASH        db    ' - ',0
  213.  
  214. NOFIND2        db    ' File not found',cr,lf,0
  215.  
  216. MATCHMSG    db    ' *Match*',cr,lf,0
  217.  
  218. ISWAS        db    ' <-- is, was --> ',0
  219.  
  220. NOTSPACE    db    'Not a space between CRC values',0
  221.  
  222. DISKFULL    db    cr,lf
  223.         db    'Disk full: CRCKLIST$'
  224.  
  225. makerr        db    cr,lf
  226.         db    "Can't make temporary file: CRCKLIST$"
  227.  
  228. dtasmall    db    cr,lf
  229.         db    'Disk transfer area too small: CRCKLIST$'
  230.  
  231. NOFIND3        db    ' ++File not found++$'
  232.  
  233. FINITO        db    cr,lf
  234.         db    'DONE$'
  235.  
  236. newln        db    cr,lf
  237. ARROW        db    '--> FILE:  '
  238. FNAME        db    'XXXXXXXX.XXX'
  239. EQUALS        db    tab,tab,'CRC = ',0
  240.  
  241. BADopen        db    ' ++Open failed++',0
  242.  
  243. READERR        db    tab,tab
  244. ;        db    ' ++File read error++'
  245.         db    cr,lf,0
  246.  
  247. abtext        db    cr,lf
  248.         db    "Can't close CRC file$"
  249.  
  250. ABORT        db    cr,lf,cr,lf
  251.         db    '++ABORTED++$'
  252.  
  253. CRCMATCH    db    'Quantity of file CRC that matched - ',0
  254.  
  255. CRCNOMATCH    db    'Quantity of file CRC that did not match - ',0
  256.  
  257. BADPARSE    db    'Quantity of lines failed parse test - ',0
  258.  
  259. QTYNOFIND    db    'Quantity of file(s) not found - ',0
  260.  
  261. FCBCRCFILE    db    0,'CRCKLIST???',0
  262.         db    0,'CRCKFILE???',0
  263.         db    11 dup (?)
  264. CRCFILELEN    dw    bufsize
  265. CRCFILEPTR    db    2 dup (?)
  266.  
  267. crcouth        dw    (?)
  268. crcoutz        db    'CRCKLIST.$$$',0
  269. zstring        db    'A:????????.???',0
  270. infileh        dw    (?)
  271.  
  272. CATALOG        db    '-CATALOG???',0
  273.  
  274.  
  275. POINTER        db    2 dup (?)
  276. MATCHNO        db    (?)
  277. NOMATCH        db    (?)
  278. FAILED        db    (?)
  279. FILES        db    (?)
  280. FFLAG        db    (?)
  281. REM        db    2 dup (?)
  282. OLDCRC        db    2 dup (?)
  283. MESS        db    (?)
  284. MFFLG1        db    1
  285. CRCENTRY    dw    1
  286. MATCHFLG    db    (?)
  287. CURSOR        db     2 dup (?)
  288.  
  289.  
  290. dtabws    dw    (?)            ; dta bytes in whole sector
  291. dtabps    dw    (?)            ; dta bytes in partial sector
  292. crcbuf    db    (?)            ; buffer used by stream write
  293.  
  294. FCBFINAL    db    0,'CRCKLISTCRC',0    ; continued in dynamic area
  295.  
  296.     ; start of dynamic storage area - this storage area is not allocated,
  297.     ; the addresses are merely defined with daisy chained equates so that
  298.     ; no space is taken up in the EXE file. This technique depends on
  299.     ; the DATA segment being loaded higher than any other segment.
  300.     ;
  301. dsa        equ    $
  302. FCBFINAL_cont    equ    dsa            ; db 24 dup (?) must be 1st
  303. buffer        equ    FCBFINAL_cont+24    ; db 80 dup (?)
  304. fcb        equ    buffer+80        ; db 12 dup (?)
  305. fcbext        equ    fcb+12            ; db 4 dup (?)
  306. fcb2        equ    fcbext+4        ; db 16 dup (?)
  307. fcbrno        equ    fcb2+16            ; db 5 dup (?)
  308. MFREQ        equ    fcbrno+5        ; db 12 dup (?)
  309. MFCUR        equ    mfreq+12        ; db 12 dup (?)
  310. crcfilebuf     equ    mfcur+12        ; db bufsizl dup (?)
  311. dta        equ    crcfilebuf+bufsizl    ; open ended - must be last
  312.  
  313. data    ENDS
  314.  
  315.  
  316.  
  317.  
  318. ; program starts here
  319. ;-------------------- 
  320. ;
  321. code    SEGMENT PARA PUBLIC
  322.     assume CS:code            ; this segment
  323.     assume DS:basepg        ; DS points at base page for now
  324.     assume SS:a_stack        ; stack segment
  325.  
  326. crck:
  327.  
  328.     mov    AX,data            ; init extra segment to point
  329.     mov    ES,AX            ;  to our program data area
  330.     assume    ES:data
  331.  
  332.     ; copy base page to prog data area
  333.     ;
  334.     mov    SI,offset dfcb        ; base page fcb to source index
  335.     mov    DI,offset fcb        ; prog data area fcb to dest index
  336.     mov    CX,37            ; # of bytes to copy
  337.     rep    movsb            ; block copy
  338.     mov    SI,offset ddta        ; base page DMA to source index
  339.     mov    DI,offset dta        ; prog data area DMA to dest index
  340.     mov    CX,40h            ; # of words to copy
  341.     rep    movsw            ; block copy
  342.  
  343.  
  344.     ; point DS register at program data area
  345.     ;
  346.     push    ES
  347.     pop    DS
  348.     assume    DS:data
  349.  
  350.     ; intercept the ctl-C interrupt vector
  351.     ;
  352.     mov    AH,setiv
  353.     mov    AL,23h
  354.     mov    DX, offset abext2    ; point it to our routine
  355.     push    DS            ; save program data segment
  356.     push    CS            ; put code segment into
  357.     pop    DS            ;  DS for interrupt handler
  358.     int    dos
  359.     pop    DS            ; restore our data segment
  360.  
  361.     ; turn on extended ctl-c detection
  362.     ;
  363.     mov    AH,33h
  364.     mov    AL,1
  365.     mov    DL,1
  366.     int    dos
  367.     
  368. START:
  369.     call    CRLF            ; turn up a new line
  370.     mov    DX,offset SIGNON    ; Tell them who we are
  371.     call    DISPLAY
  372.     mov    AL,Byte Ptr FCB+1    ;Point to file name
  373.     cmp    AL,' '            ;Is it there?
  374.     jz    CONTINUE
  375.     jmp    FILE_OUT_CHECK        ;Yes
  376.  
  377. CONTINUE:
  378.  
  379.     mov    DX,offset SRCH_LIST    ;Searching for CRCKLIST.??? file
  380.     call    DISPLAY
  381.     call    OPENCRCFILE
  382.     jz    PROCESSIT
  383.     mov    DX,offset SRCH_FILE
  384.     call    DISPLAY            ;Searching for CRCKFILE.??? file
  385.     mov    SI,Offset FIRST_TRY
  386.     mov    DI,Offset FCBCRCFILE+1
  387.     mov    CX,11
  388.     rep    movsb
  389.     call    OPENCRCFILE
  390.     jz    PROCESSIT
  391.     jmp    CATCHECK
  392.  
  393. PROCESSIT:
  394.     call    FINDCRC
  395.     jz    PROCESS2
  396.     jmp    ABEXT2
  397.  
  398. PROCESS2:
  399.     mov    DX,offset ARROW
  400.     mov    BX,offset buffer
  401.     mov    CX,11
  402.     call    COMPARE
  403.     jnz    NONSENSE
  404.     call    ISNAME
  405.     jnz    NONSENSE
  406.     mov    DX,offset EQUALS
  407.     mov    CL,31
  408.     call    COMPARE
  409.     jnz    NONSENSE
  410.     call    STORECRC
  411.     jnz    NONSENSE
  412.     mov    BX,offset buffer+11
  413.     call    SHOWNAME
  414.     jmp    short PROCESSIT
  415.  
  416. NONSENSE:
  417.     call    NOPARSE
  418.     jmp    short PROCESSIT
  419.  
  420.     ; -CATALOG and CRCKLIST read routine
  421.     ;
  422. READFILE:
  423.     mov    BX,word ptr crcfileptr        ; get the buffer pointer
  424.     cmp    BX,offset crcfilebuf+bufsizl    ; see if points to end
  425.     jnz    readabyte            ; if not, go get a byte
  426.     mov    BX,offset crcfilebuf    ; else, load buffer address
  427.     mov    Word Ptr CRCFILEPTR,BX    ; reset buffer pointer to it
  428. READLOOP:
  429.     mov    DX,BX            ; get buffer address into DX
  430.     mov    AH,setdta        ; point dta at it
  431.     int    dos
  432.     mov    DX,offset FCBCRCFILE    ; get fcb address
  433.     mov    AH,read            ; read a sector
  434.     int    dos
  435.     or    AL,AL            ; see if read a whole sector
  436.     jz    rl_2            ; if so, continue
  437.     cmp    AL,3            ; see if read a partial sector
  438.     jnz    LASTread        ; if not, must be eof or error
  439. rl_2:
  440.     add    BX,secsizs        ; move buffer ptr by a sector
  441.     cmp    BX,offset crcfilebuf+bufsizl    ; see if BX points to end
  442.     jnz    READLOOP
  443.     jmp    short resetdma        
  444.  
  445. LASTREAD:
  446.     mov    Word Ptr CRCFILELEN,BX    ; make sure file length correct
  447. resetdma:
  448.     mov    DX,offset dta        ; point back to dta of data file
  449.     mov    AH,setdta
  450.     int    dos
  451.     mov    BX,Word Ptr CRCFILEPTR ; get buffer pointer back
  452. READABYTE:
  453.     cmp    BX,word ptr crcfilelen
  454.     mov    AL,eof
  455.     jnz    READBYTE1
  456.     ret
  457. READBYTE1:
  458.     mov    AL,byte ptr [BX]
  459.     inc    BX
  460.     mov    word ptr crcfileptr, BX
  461.     ret
  462.  
  463. OPENCRCFILE:
  464.     xor    AL,AL
  465.     mov    Byte Ptr FCBCRCFILE+12,AL
  466.     mov    Byte Ptr FCBCRCFILE+32,AL
  467.     mov    BX,offset crcfilebuf+bufsizl    ; point to end of buffer
  468.     mov    word ptr crcfileptr,BX        ; init buffer ptr to it
  469.     mov    word ptr crcfilelen,BX        ; and also the file length
  470.     mov    SI,offset FCBCRCFILE    ;CCP/M doesn't like "?" in
  471.     mov    DI,offset FCB        ; OPEN function calls, so 
  472.     mov    CX,6            ; since we already have
  473.     rep    movsw            ; MFNAME in the code, use it to 
  474.     call    MFNAME            ; get a definitive filename
  475.     jb    OPENFAIL        ; to attempt an open. Only
  476.     mov    SI,offset FCB        ; the first matching name is
  477.     mov    DI,offset FCBCRCFILE    ; tried for an open, but this is all
  478.     mov    CX,6            ; the orginal code achieved anyway.
  479.     rep    movsw
  480.     mov    AH,OPEN
  481.     mov    DX,offset FCBCRCFILE
  482.     int    dos
  483.     inc    AL
  484.     jnz    FILEMATCH
  485. OPENFAIL:
  486.     mov    AH,print
  487.     mov    DX,offset NOFILECRC
  488.     int    dos
  489.     jmp    FILERR
  490.  
  491. FILEMATCH:
  492.     mov    SI,offset FCBCRCFILE+1
  493.     mov    DI,offset buffer
  494.     mov    CX,4
  495.     rep    movsw
  496.     mov    AL,'.'
  497.     mov    byte ptr [DI],AL
  498.     inc    DI
  499.     mov    CX,3
  500.     rep    movsb
  501.     xor    AL,AL
  502.     mov    byte ptr [DI],AL
  503.     mov    DX,offset CHECKING    ;Show which file we are checking
  504.     call    DISPLAY
  505.     mov    BX,offset buffer
  506. MATCHLOOP:
  507.     mov    AL,byte ptr [BX]
  508.     or    AL,AL
  509.     jz    MATCHINIT
  510.     call    TYPER
  511.     inc    BX
  512.     jmp    short MATCHLOOP
  513.  
  514. MATCHINIT:
  515.     call    CRLF
  516.     call    CRLF
  517.     xor    AL,AL
  518.     mov    Byte Ptr MATCHNO,AL
  519.     mov    Byte Ptr NOMATCH,AL
  520.     mov    Byte Ptr FAILED,AL
  521.     mov    Byte Ptr FILES,AL
  522.     ret
  523.  
  524. FINDCRC:
  525.     mov    BX,offset buffer
  526.     mov    AL,0
  527.     mov    Byte Ptr CURSOR,AL    ;Reset cursor counter to start of line
  528. FINDCRC1:
  529.     push    BX
  530.     call    READFILE
  531.     pop    BX
  532.     cmp    AL,eof
  533.     jnz    FINDCRC2
  534.     mov    AL,Byte Ptr CURSOR
  535.     or    AL,AL
  536.     jnz    FINDDONE
  537.     mov    AL,Byte Ptr CRCENTRY
  538.     or    AL,AL
  539.     jnz    FINDCRC1A
  540.     jmp    DONEIT
  541.  
  542. FINDCRC1A:
  543.     mov    DX,offset NOFIND    ;File not found
  544.     call    DISPLAY
  545.     mov    AL,eof
  546.     or    AL,AL
  547.     ret
  548.  
  549. FINDCRC2:
  550.     and    AL,07FH            ;Make sure its ASCII
  551.     cmp    AL,cr            ;End of line?
  552.     jz    ENDOFLINE        ;Yes
  553.     cmp    AL,lf            ;End of line?
  554.     jz    ENDOFLINE        ;Yes
  555.     mov    byte ptr [BX],AL            ;No
  556.     inc    BX
  557.     mov    AL,Byte Ptr CURSOR    ;Bump cursor pointer
  558.     inc    AL
  559.     mov    Byte Ptr CURSOR,AL
  560.     cmp    AL,80            ;End of line?
  561.     jb    FINDCRC1        ;No
  562. ENDOFLINE:
  563.     mov    AL,Byte Ptr CURSOR
  564.     or    AL,AL
  565.     jz    FINDCRC
  566. FINDDONE:
  567.     mov    byte ptr [BX],0
  568.     xor    AL,AL
  569.     ret
  570.  
  571. NOPARSE:
  572.         if no_parse_msg
  573.     mov    DX,offset CANTPARSE    ;Cant parse string
  574.     call    DISPLAY
  575.         endif
  576.  
  577.     mov    BX,offset buffer
  578. PARSELOOP:
  579.     mov    AL,byte ptr [BX]
  580.     or    AL,AL
  581.     jz    SHOWERR
  582.     call    TYPER
  583.     inc    BX
  584.     jmp    short PARSELOOP
  585. ;
  586. SHOWERR:
  587.         if no_parse_msg
  588.     call    CRLF
  589.         endif
  590.  
  591.     mov    BX,offset buffer
  592.     inc    CH
  593.     dec    CH
  594.     jz    SHOWERR3
  595. SHOWERR1:
  596.     mov    AL,tab
  597.     cmp    AL,byte ptr [BX]
  598.     jz    SHOWERR2
  599.     mov    byte ptr [BX],' '
  600. SHOWERR2:
  601.     inc    BX
  602.     dec    CH
  603.     jnz    SHOWERR1
  604. SHOWERR3:
  605.     mov    byte ptr [BX],'^'
  606.     inc    BX
  607.     mov    byte ptr [BX],0
  608.     mov    BX,offset buffer
  609. SHOWERR4:
  610.     mov    AL,byte ptr [BX]
  611.     or    AL,AL
  612.     jz    RECORDERR
  613.  
  614.         if no_parse_msg
  615.     call    TYPER
  616.         endif
  617.  
  618.     inc    BX
  619.     jmp    short SHOWERR4
  620.  
  621. RECORDERR:
  622.     mov    BX,offset FAILED
  623.     inc    byte ptr [BX]
  624.     call    CRLF
  625.     ret
  626. ;
  627. COMPARE:
  628.     mov    SI,DX
  629.     mov    AL,byte ptr [SI]
  630.     cmp    AL,byte ptr [BX]
  631.     jz    COMPARE1
  632.     ret
  633. ;
  634. COMPARE1:
  635.     inc    BX
  636.     inc    DX
  637.     inc    CH
  638.     mov    AL,CH
  639.     cmp    AL,CL
  640.     jnz    COMPARE2
  641.     ret
  642. ;
  643. COMPARE2:
  644.     jmp    short COMPARE
  645. ;
  646. SHOWNAME:
  647.     mov    SI,BX
  648.     mov    DI,offset fcb+1
  649.     mov    CX,4
  650.     rep    movsw
  651.     inc    SI
  652.     mov    CX,3
  653.     mov    DI,offset fcb+9
  654.     rep    movsb
  655.     xor    AL,AL
  656.     mov    byte ptr [SI],AL
  657. SHOWLOOP:
  658.     mov    AL,byte ptr [BX]
  659.     or    AL,AL
  660.     jz    SHOWDONE
  661.     call    TYPER
  662.     inc    BX
  663.     jmp    short SHOWLOOP
  664. ;
  665. SHOWDONE:
  666.     mov    AL,1
  667.     mov    Byte Ptr MFFLG1,AL
  668.     mov    DX,offset DASH        ;Display delimiter
  669.     call    DISPLAY
  670.     call    MFNAME
  671.     jnb    TRYMATCH
  672.     mov    DX,offset NOFIND2
  673.     call    DISPLAY
  674.     mov    BX,offset FILES
  675.     inc    byte ptr [BX]
  676.     xor    AL,AL
  677.     inc    AL
  678.     ret
  679.  
  680. TRYMATCH:
  681.     mov    AL,1
  682.     mov    Byte Ptr MATCHFLG,AL    ;We found some filenames to check
  683.     call    OPENIT
  684.     jz    TRYMATCH1
  685.     ret
  686.  
  687. TRYMATCH1:
  688.     mov    AL,Byte Ptr OLDCRC+1
  689.     mov    CH,AL
  690.     mov    AL,Byte Ptr REM
  691.     cmp    AL,CH
  692.     jnz    MISMATCH
  693.     mov    AL,Byte Ptr OLDCRC
  694.     mov    CH,AL
  695.     mov    AL,Byte Ptr REM+1
  696.     cmp    AL,CH
  697.     jnz    MISMATCH
  698.     mov    DX,offset MATCHMSG    ; *Match*
  699.     call    DISPLAY
  700.     xor    AL,AL
  701.     mov    Byte Ptr CRCENTRY,AL
  702.     mov    BX,offset MATCHNO
  703.     inc    byte ptr [BX]
  704.     xor    AL,AL
  705.     ret
  706.  
  707. MISMATCH:
  708.     mov    DX,offset ISWAS        ; <--is, was -->
  709.     call    DISPLAY
  710.     mov    AL,Byte Ptr OLDCRC
  711.     call    HEXO
  712.     mov    AL,' '
  713.     call    TYPER
  714.     mov    AL,Byte Ptr OLDCRC+1
  715.     call    HEXO
  716.     call    CRLF
  717.     xor    AL,AL
  718.     mov    Byte Ptr CRCENTRY,AL
  719.     mov    BX,offset NOMATCH
  720.     inc    byte ptr [BX]
  721.     xor    AL,AL
  722.     inc    AL
  723.     ret
  724.  
  725. STORECRC:
  726.     call    HEXBIN
  727.     jz    STORECRC0
  728.     ret
  729.  
  730. STORECRC0:
  731.     mov    Byte Ptr OLDCRC,AL
  732.     mov    AL,byte ptr [BX]
  733.     inc    BX
  734.     cmp    AL,' '
  735.     jz    STORECRC1
  736.     mov    DX,offset NOTSPACE    ;No space between CRC values
  737.     call    DISPLAY
  738.     xor    AL,AL
  739.     inc    AL
  740.     ret
  741.  
  742. STORECRC1:
  743.     call    HEXBIN
  744.     jz    STORECRC2
  745.     ret
  746.  
  747. STORECRC2:
  748.     mov    Byte Ptr OLDCRC+1,AL
  749.     mov    CH,AL
  750.     xor    AL,AL
  751.     ret
  752.  
  753. CATCHECK:
  754.     mov    DX,offset SRCH_CAT    ;Searching -CATALOG file
  755.     call    DISPLAY
  756.     mov    SI,offset CATALOG
  757.     mov    DI,offset FCBCRCFILE+1
  758.     mov    CX,11
  759.     rep    movsb
  760.     call    OPENCRCFILE
  761.     jz    PARSELINE
  762.     jmp    ABEXT2
  763. ;
  764. PARSELINE:
  765.     call    FINDCRC
  766.     jz    PARSE2
  767.     jmp    ABEXT2
  768. ;
  769. PARSE2:
  770.     mov    CH,0
  771.     mov    BX,offset buffer    ;Point to catalog entry
  772.     call    THREENUM        ;Check for 3 digit volume number
  773.     jnz    TRYAGAIN
  774.     mov    AL,'.'            ;Followed by separator
  775.     cmp    AL,byte ptr [BX]
  776.     jnz    TRYAGAIN
  777.     lahf
  778.     inc    BX
  779.     sahf
  780.     inc    CH
  781.     call    TWONUM            ;Check for 2 digit entry number
  782.     jnz    TRYAGAIN
  783.     call    ISWHITE            ;Skip over white space
  784.     jnz    TRYAGAIN
  785.     call    ISNAME            ;Check for valid file name
  786.     jnz    TRYAGAIN
  787.     call    ISWHITE            ;Skip over white space
  788.     jnz    NOGOOD
  789.     call    ISNUM            ;Check for first digit of filesize
  790.     jnz    NOGOOD
  791. SKIP:
  792.     call    ISNUM
  793.     jz    SKIP
  794.     cmp    AL,'K'            ;Filesize ends in K
  795.     jnz    NOGOOD
  796.     call    ISWHITE            ;Skip over white space
  797.     jnz    NOGOOD
  798.     call    STORECRC        ;Now we should be at the CRC
  799.     jnz    NOGOOD
  800.     mov    BX,Word Ptr POINTER
  801.     call    SHOWNAME
  802.     jmp    short PARSELINE
  803. ;
  804. TRYAGAIN:
  805.     mov    AL,Byte Ptr CRCENTRY
  806.     or    AL,AL
  807.     jnz    PARSELINE
  808. NOGOOD:
  809.     call    NOPARSE
  810.     jmp    PARSELINE
  811. ;
  812. ISNAME:
  813.     mov    Word Ptr POINTER,BX
  814.     call    ISALPHA            ;Check first character
  815.     jz    ISNAME0
  816.     ret
  817. ;
  818. ISNAME0:
  819.     mov    CL,7            ;7 left in rest of filename
  820. ISNAME1:
  821.     call    ISALPHA
  822.     jz    ISNAME2
  823.     cmp    AL,' '            ;Maybe padded with spaces?
  824.     jz    ISNAME2
  825.     ret
  826. ;
  827. ISNAME2:
  828.     dec    CL            ;Done?
  829.     jnz    ISNAME1            ;No
  830.     mov    AL,byte ptr [BX]            ;Yes
  831.     inc    BX
  832.     inc    CH
  833.     cmp    AL,'.'            ;Valid separator?
  834.     jz    ISNAME3
  835.     ret
  836. ;
  837. ISNAME3:
  838.     mov    CL,3            ;3 in filetype
  839. ISNAME4:
  840.     call    ISALPHA
  841.     jz    ISNAME5
  842.     cmp    AL,' '            ;Padded with spaces
  843.     jz    ISNAME5
  844.     ret
  845. ;
  846. ISNAME5:
  847.     dec    CL            ;Done?
  848.     jnz    ISNAME4            ;No
  849.     ret                ;Yes
  850. ;
  851. ISWHITE:
  852.     mov    AL,byte ptr [BX]
  853.     cmp    AL,' '            ;Space?
  854.     jz    WHITELOOP        ;Yes, check some more
  855.     cmp    AL,tab            ;No, maybe a tab?
  856.     jz    WHITELOOP
  857.     ret                ;No, something else
  858. ;
  859. WHITELOOP:
  860.     inc    BX            ;Point to next char
  861.     inc    CH
  862.     mov    AL,byte ptr [BX]
  863.     cmp    AL,' '            ;Space?
  864.     jz    WHITELOOP        ;Yes, check some more
  865.     cmp    AL,tab            ;No, maybe a tab? 
  866.     jz    WHITELOOP        ;Yes, check some more
  867.     cmp    AL,AL            ;No, something else
  868.     ret
  869. ;
  870. THREENUM:
  871.     call    TWONUM
  872.     jz    THREENUM1
  873.     ret
  874. ;
  875. THREENUM1:
  876.     call    ISNUM
  877.     jnz    THREENUM2
  878.     ret
  879. ;
  880. THREENUM2:
  881.     cmp    AL,'.'
  882.     jz    THREENUM3
  883.     ret
  884. ;
  885. THREENUM3:
  886.     dec    BX
  887.     dec    CH
  888.     cmp    AL,AL
  889.     ret
  890. ;
  891. TWONUM:
  892.     call    ISNUM
  893.     jz    ISNUM
  894.     ret
  895. ;
  896. ISNUM:
  897.     mov    AL,byte ptr [BX]
  898.     inc    BX
  899.     inc    CH
  900.     cmp    AL,'0'
  901.     jb    NOTNUM
  902.     cmp    AL,'9'+1
  903.     jnb    NOTNUM
  904.     cmp    AL,AL
  905.     ret
  906. ;
  907. NOTNUM:
  908.     cmp    AL,'0'
  909.     ret
  910. ;
  911. ISALPHA:
  912.     mov    AL,byte ptr [BX]
  913.     inc    BX
  914.     inc    CH
  915.     cmp    AL,' '+1
  916.     jb    ALPHA1
  917.     cmp    AL,07Fh
  918.     jnb    ALPHA1
  919.     cmp    AL,AL
  920.     ret
  921.  
  922. ALPHA1:
  923.     cmp    AL,'A'
  924.     ret
  925.  
  926. HEXBIN:
  927.     call    MAKEBIN
  928.     jz    HEXBIN1
  929.     ret
  930.  
  931. HEXBIN1:
  932.     ROL    AL,1
  933.     ROL    AL,1
  934.     ROL    AL,1
  935.     ROL    AL,1
  936.     mov    CL,AL
  937.     call    MAKEBIN
  938.     jz    HEXBIN2
  939.     ret
  940.  
  941. HEXBIN2:
  942.     mov    CH,AL
  943.     mov    AL,CL
  944.     or    AL,CH
  945.     cmp    AL,AL
  946.     ret
  947. ;
  948. MAKEBIN:
  949.     mov    AL,byte ptr [BX]
  950.     inc    BX
  951.     inc    CH
  952.     cmp    AL,'0'
  953.     jb    MAKEBIN2
  954.     sub    AL,'0'
  955.     cmp    AL,10
  956.     jb    MAKEBIN1
  957.     and    AL,1FH
  958.     sub    AL,7H
  959.     cmp    AL,10
  960.     jb    MAKEBIN2
  961.     cmp    AL,16
  962.     jnb    MAKEBIN2
  963. MAKEBIN1:
  964.     cmp    AL,AL            ;Return zero flag not set
  965.     ret
  966.  
  967. MAKEBIN2:
  968.     or    AL,AL            ;Return zero flag set
  969.     ret
  970.  
  971. FILE_OUT_CHECK:
  972.     mov    AL,Byte Ptr FCB2+1    ;Point to possible file write command
  973.     mov    Byte Ptr FFLAG,AL    ;Save as a flag
  974.     cmp    AL,'F'            ;Is it the correct one?
  975.     jz    makecrcfile        ;Yes
  976.     jmp    AGAIN            ;NO
  977.  
  978. putcrcfile:
  979.     mov    byte ptr crcbuf,AL
  980.     mov    DX, offset crcbuf
  981.     mov    CX,1
  982.     mov    BX, word ptr crcouth    ; stream # to BX
  983.     mov    AH,wrtstr        ;write 1 char to -catalog file stream
  984.     int    dos
  985.     jnc    putcrc_4
  986.     cmp    AX,5
  987.     jz    putcrc_1
  988.     cmp    AX,6
  989.     jz    putcrc_2
  990.     ret
  991. putcrc_1:
  992.     mov    DX,offset diskfull
  993.     jmp    short putcrc_3
  994. putcrc_2:
  995.     mov    DX,offset dtasmall
  996. putcrc_3:
  997.     mov    AH,print
  998.     int    dos
  999.     jmp    filerr
  1000. putcrc_4:
  1001.     ret
  1002.  
  1003. makecrcfile:
  1004.     mov    DX, offset crcoutz    ; z-string of tmp crc output file
  1005.     xor    CX,CX            ; no file attribute
  1006.     mov    AH,makstr        ; make file & stream
  1007.     int    dos
  1008.     mov    word ptr crcouth,AX    ; save the stream #
  1009.     jnc    again            ; if no error, start file lookup
  1010.     mov    AH,print        ; else print error message
  1011.     mov    DX,offset makerr
  1012.     int    dos
  1013.     jmp    abext2
  1014.  
  1015. AGAIN:
  1016.     mov    Byte Ptr MATCHFLG,0
  1017.     call    MFNAME
  1018.     JNAE    AGAIN1
  1019.     jmp    DOFILECRC
  1020. ;
  1021. AGAIN1:
  1022.     mov    AL,Byte Ptr MFFLG1
  1023.     or    AL,AL
  1024.     jz    DONE
  1025.     mov    DX,offset NOFIND3
  1026.     mov    AH,print
  1027.     int    dos
  1028.     jmp    ABEXT2
  1029.  
  1030. DONE:
  1031.     mov    AL,Byte Ptr FFLAG    ; get outfile open flag
  1032.     cmp    AL,'F'            ; see if outfile open
  1033.     jnz    doneit            ; skip file stuff if not
  1034.  
  1035. CLOSEIT:
  1036.     call    crlf
  1037.     mov    AL,eof
  1038.     call    putcrcfile
  1039.     mov    AH,clostr        ; Close stream
  1040.     mov    BX,word ptr crcouth    ; CRCKLIST.$$$ stream number
  1041.     int    dos
  1042.     jnc    ERASEIT            ; continue if carry not set
  1043.     mov    AH,print        ; else, print error message
  1044.     mov    DX,offset abtext
  1045.     int    dos
  1046.     jmp    filerr
  1047.  
  1048.     ;Erase any existing CRCKLIST.CRC file
  1049.     ;
  1050. ERASEIT:
  1051.     mov    AH,delete
  1052.     mov    DX,offset FCBFINAL
  1053.     int    dos
  1054.  
  1055. RENLOOP:
  1056.     mov    SI,offset crcoutz+9    ; location of '$$$' in z-string
  1057.     mov    DI,offset fcbcrcfile+9    ; location of fcb1 filetype
  1058.     mov    CX,3            ; # of bytes
  1059.     rep    movsb            ; block move
  1060.     mov    SI,offset fcbfinal    ; start of CRCFILE.CRC filename
  1061.     mov    DI,offset fcbcrcfile+16    ; location of fcb2
  1062.     mov    CX,12            ; # of bytes
  1063.     rep    movsb            ; block move
  1064.     mov    DX,offset fcbcrcfile    ; address of modified fcb
  1065.     mov    AH,rename        ; Rename CRCKLIST.$$$ to CRCKLIST.CRC
  1066.     int    dos
  1067. DONEIT:
  1068.     mov    DX,offset FINITO
  1069.     jmp    SIGNOFF
  1070.  
  1071. DOFILECRC:
  1072.     mov    BX,offset fcb+9        ; point BX at the file type
  1073.     call    TSTBAD            ; test for $$$ filetype
  1074.     jnz    DOFILECRC0        ; continue if not
  1075.     jmp    AGAIN            ; else get another file name
  1076.  
  1077. dofilecrc0:
  1078.     cmp    byte ptr fcb+1,'-'    ; see if filename starts with a dash
  1079.     jnz    dofilecrc1        ; continue if not
  1080.     jmp    again            ; else skip it
  1081.  
  1082. DOFILECRC1:
  1083.     mov    SI,offset fcb+1        ; copy file name from fcb
  1084.     mov    DI,offset FNAME        ;  to display string
  1085.     mov    CX,4            ;  consisting of 8 characters
  1086.     rep    movsw            ;  with a block move
  1087.     mov    SI,offset fcb+9        ; also copy the fcb file type
  1088.     mov    DI,offset FNAME+9    ;  into the display string
  1089.     mov    CX,3            ;  which is 3 characters long
  1090.     rep    movsb            ;  with a block move
  1091.     mov    DX,offset newln        ; now display it
  1092.     call    DISPLAY
  1093.     call    OPENIT            ; open file ref'd by fcb
  1094.     jnz    DOFILECRC3        ; if 0 not ret'd, bad open
  1095.     jmp    AGAIN            ; else continue
  1096.  
  1097. DOFILECRC3:
  1098.     jmp    ABEXT2
  1099.  
  1100.     ; before opening the file we're going to do the crck on,
  1101.     ; compute optimum record sizes
  1102. openit:
  1103.  
  1104.     mov    BX,word ptr dta+1Dh    ; get file size low word to BX
  1105.     mov    CX,word ptr dta+1Fh    ; get file size high word to CX
  1106.     add    BX,7Fh            ; bump to next 128 byte boundary
  1107.     adc    CX,0            ; add any carry to CX
  1108.     and    BL,80h            ; mask off bottom 7 bits
  1109.     mov    word ptr dtabps,BX
  1110.     mov    word ptr dtabws,BX
  1111.  
  1112.     ; double-word size less than maximum size of dta?
  1113. dwltm:    or    CX,CX            ; BX = 0 ? ( < 64K? )
  1114.     jnz    dwltmNO            ; NO, then max bws & figure bps
  1115.     cmp    BX,dtamax        ; check the low word
  1116.     jbe    dwltmYES        ; YES, set bws to file size
  1117. dwltmNO:
  1118.     mov    word ptr dtabws,dtamax    ; set bytes in whole sector max
  1119. reduce:
  1120.     ; compute number of bytes in the final partial record
  1121.     sub    BX,dtamax        ; reduce low word by dtamax
  1122.     sbb    CX,0            ;  & subtract any borrow from BX
  1123.  
  1124.     ; compare double word to maximum dta size
  1125.     or    CX,CX            ; less than 64K ?
  1126.     jnz    reduce            ; if not, reduce some more
  1127.     cmp    BX,dtamax        ; low word <= dtamax ?
  1128.     jnb    reduce            ; if neither, reduce some more
  1129.  
  1130.     mov    word ptr dtabps,BX    ; save partial record size
  1131.     jmp    short rdinit
  1132.  
  1133. dwltmYES:
  1134.     mov    word ptr dtabws,BX    ; set whole sector size to file size
  1135.  
  1136.     ; initialization to read the file we're doing the crck on
  1137. rdinit:
  1138.     ; unparse from file control block into zstring
  1139.     mov    SI,offset fcb        ; filename address in SI
  1140.     mov    DI,offset zstring    ; zstring address in DI
  1141.     movsb
  1142.     add    byte ptr zstring,40h
  1143.     inc    DI
  1144.     mov    CX,8            ; # of bytes
  1145.     rep    movsb
  1146.     inc    DI            ; skip over decimal point
  1147.     mov    CX,3            ; # of bytes in filetype
  1148.     rep    movsb            ; block move
  1149.  
  1150.     mov    AH,opnstr        ; open file stream
  1151.     xor    AL,AL            ; read only mode
  1152.     mov    DX,offset zstring    ; file to open
  1153.     int    dos
  1154.     mov    word ptr infileh,AX    ; save the input file handle
  1155.     jnc    rdinit_1        ; if no error, continue
  1156.     mov    DX,offset BADOPEN    ; else, tell operator
  1157.     call    DISPLAY
  1158.     call    crlf
  1159.     xor    AL,AL
  1160.     inc    AL            ; ret NZ for bad open
  1161.     ret
  1162.  
  1163.     ; register usage during read loop as follows:
  1164.     ;    AH = dos function number & flag holder
  1165.     ;    AL = target of load byte from buffer
  1166.     ;    AX = # of bytes to read from the file stream
  1167.     ;    BX = accumulated CRC remainder & file stream handle
  1168.     ;    CX = count of # of bytes in buffer
  1169.     ;    DX = buffer beginning address
  1170.     ;    SI = pointer to next character in buffer
  1171.     ;    DI = pointer to end of partial record
  1172.     ;
  1173. rdinit_1:
  1174.     xor    BX,BX            ; init crc accumulator to 0
  1175.     mov    DX,offset dta        ; point DX at start of buffer
  1176.  
  1177.     ; routine to refill the dta
  1178.     ;
  1179. filldta:
  1180.     mov    AH,redstr        ; read a record from file
  1181.     mov    word ptr REM,BX        ; save the CRC remainder
  1182.     mov    BX,word ptr infileh    ; put stream # in BX
  1183.     mov    CX,word ptr dtabws    ; get # bytes in full record
  1184.     mov    SI,DX            ; point to beginning of buffer
  1185.     int    dos
  1186.     mov    BX,word ptr REM        ; restore the CRC remainder
  1187.     cmp    CX,AX            ; see if full record returned
  1188.     jz    readit            ; if so, process it
  1189.     or    AX,AX
  1190.     jz    short finish        ; if 0, its eof
  1191.     mov    CX,word ptr dtabps    ; else, get # bytes in partial sector
  1192.     cmp    AX,CX            ; see if >= partial sector
  1193.     jae    readit            ; if so, process it
  1194.     mov    DI,DX            ; 
  1195.     add    DI,AX            ; point DI past last byte returned
  1196.     push    CX
  1197.     sub    CX,AX
  1198.     xor    AL,AL            ; put null into AL
  1199.     rep    stosb            ; clear till boundary
  1200.     pop    CX
  1201.  
  1202.     ; Fred Gutman's CRC generator from EDN, June 5, 1979, page 84
  1203.     ; optimized for the 8086 by Howard Vigorita
  1204.     ;
  1205. readit:
  1206.     test    BH,128            ; Q-bit mask accumulated crc
  1207.     lahf                ; save status flags in AH
  1208.     shl    BX,1            ; double old crc
  1209.     lodsb                ; AL = byte ptr [SI++]
  1210.     add    BL,AL            ; add in new char
  1211.     sahf                ; restore the flags from AH
  1212.     jz    readit_1        ; skip mask if Q-bit was zero
  1213.     xor    BX,0A097h        ; CCIT CRC polynomial mask bytes
  1214. readit_1:
  1215.     loop    readit            ; go read more characters
  1216.     jmp    short filldta        ; if none left, refill the dta
  1217.  
  1218. FINISH:
  1219.     or    AL,AL            ;Normal end of file?
  1220.     jz    FINISH1            ;Yes
  1221.     call    closer2
  1222.     jmp    FILERR            ;No, it was a read error
  1223.  
  1224. FINISH1:
  1225.     mov    AL,Byte Ptr REM+1    ; Get top byte of CRC
  1226.     call    HEXO            ; Display it
  1227.     mov    AL,' '            ; space between CRC bytes
  1228.     call    TYPER
  1229.     mov    AL,Byte Ptr REM        ; Get bottom byte of CRC
  1230.     call    HEXO            ; Display it
  1231.     call    closer2            ; close file we crck'd
  1232.     xor    AL,AL            ; ret with Z set to tell
  1233.     ret                ;  caller all went well
  1234. ;
  1235. FILERR:
  1236.     mov    DX,offset READERR
  1237.     call    DISPLAY
  1238.     xor    AL,AL
  1239.     inc    AL
  1240.     ret
  1241. ;
  1242. CLOSER:
  1243.     mov    DX,offset fcb
  1244.     mov    AH,CLOSE
  1245.     int    dos
  1246.     ret
  1247.  
  1248. closer2:
  1249.     mov    BX,word ptr infileh
  1250.     mov    AH,clostr
  1251.     int    dos
  1252.     ret
  1253.  
  1254.     ; output ascii hex of the byte in AL
  1255.     ;
  1256. HEXO:
  1257.     lahf                ;SAVE FOR RIGHT DIGIT
  1258.     xchg    AL,AH
  1259.     push    AX
  1260.     xchg    AL,AH
  1261.     RCR    AL,1            ;RIGHT..
  1262.     RCR    AL,1            ;..JUSTIFY..
  1263.     RCR    AL,1            ;..LEFT..
  1264.     RCR    AL,1            ;..DIGIT..
  1265.     call    NIBBL            ;PRINT LEFT DIGIT
  1266.     pop    AX            ;RESTORE RIGHT
  1267.     xchg    AL,AH
  1268.  
  1269. NIBBL:
  1270.     and    AL,0FH            ;ISOLATE DIGIT
  1271.     cmp    AL,10            ;IS IS <10?
  1272.     jb    NOTALPHA        ;YES, NOT ALPHA
  1273.     add    AL,7            ;add ALPHA BIAS
  1274.  
  1275. NOTALPHA:
  1276.     add    AL,'0'            ;MAKE PRINTABLE
  1277.     jmp    short TYPER        ;PRINT IT, THEN RETURN
  1278.  
  1279.     ; substitute for inline print routine
  1280.     ;    prints null terminated strings
  1281.     ;    expects string address in [DX]
  1282.     ; 
  1283. display:
  1284.     mov    BX,DX
  1285. dspl_1:    mov    AL,byte ptr [BX]    ; get char
  1286.     call    typer            ; output it
  1287.     inc    BX            ; point to next
  1288.     mov    AL,byte ptr [BX]    ; test
  1289.     or    AL,AL            ; ..for end
  1290.     jnz    dspl_1
  1291.     ret                ; ret to caller
  1292.  
  1293.     ; send carriage return, line feed to output
  1294.     ; 
  1295. crlf:    mov    AL,cr            ; carriage return
  1296.     call    typer
  1297.     mov    AL,lf            ; line feed, fall into 'type'
  1298.  
  1299.     ; send character in AL register to output
  1300.     ; 
  1301. typer:
  1302.     and    AL,7Fh            ; strip parity bit
  1303.     mov    DL,AL
  1304.     push    DX
  1305.     call    wrfile            ; write to file if requested
  1306.     pop    DX
  1307.     mov    AH,wrcon        ; send character to console
  1308.     int    dos
  1309.     ret
  1310.  
  1311.  
  1312. wrfile:
  1313.     mov    AL,Byte Ptr FFLAG
  1314.     cmp    AL,'F'            ;Write to file?
  1315.     jz    wrf_2
  1316.     ret                ;No
  1317.  
  1318. wrf_2:
  1319.     mov    AL,DL            ;Yes
  1320.     push    CX
  1321.     push    BX
  1322.     call    PUTCRCFILE
  1323.     pop    BX
  1324.     pop    CX
  1325.     ret
  1326.  
  1327.  
  1328.     ;Multi-file access subroutine.  Allows processing
  1329.     ;of multiple files (i.e. *.ASM) from disk.  This
  1330.     ;routine builds the proper name in the FCB each
  1331.     ;time it is called. Carry is set if no more names
  1332.     ;can be found.
  1333.     ;
  1334. mfname:                    ; init dma addr and fcb
  1335.     mov    AH,setdta
  1336.     mov    DX,offset dta
  1337.     int    dos
  1338.     xor    AL,AL
  1339.     mov    byte ptr fcbext,AL
  1340.     mov    byte ptr fcbrno,AL
  1341.  
  1342.     ; if first time
  1343.     ;
  1344.     mov    AL,byte ptr mfflg1
  1345.     or    AL,AL
  1346.     jz    mfn01
  1347.  
  1348.     ; save the requested name
  1349.     ;
  1350.     mov    SI,offset fcb
  1351.     mov    DI,offset mfreq
  1352.     mov    CX,6
  1353.     rep    movsw
  1354.     mov    AL,byte ptr fcb
  1355.     mov    byte ptr mfcur,AL    ; save disk in curr fcb
  1356.  
  1357.     ; srchf requested name
  1358.     ;
  1359. ;    mov    SI,offset mfreq
  1360. ;    mov    DI,offset fcb
  1361. ;    mov    CX,6
  1362. ;    rep    movsw
  1363.     mov    AH,srchf
  1364.     mov    DX,offset fcb
  1365.     int    dos
  1366.  
  1367.     ; else
  1368.     ;
  1369.     jmp    short mfn02
  1370. mfn01:                    ; srchf current name
  1371.     mov    SI,offset mfcur
  1372.     mov    DI,offset fcb
  1373.     mov    CX,6
  1374.     rep    movsw
  1375.     mov    AH,srchf
  1376.     mov    DX,offset fcb
  1377.     int    dos
  1378.  
  1379.     ; srchn requested name
  1380.     ;
  1381.     mov    SI,offset mfreq
  1382.     mov    DI,offset fcb
  1383.     mov    CX,6
  1384.     rep    movsw
  1385.     mov    AH,srchn
  1386.     mov    DX,offset fcb
  1387.     int    dos
  1388.  
  1389.     ; endif
  1390.     ;
  1391. mfn02:                    ; return carry if not found
  1392.     inc    AL
  1393.     STC
  1394.     jnz    mfn03
  1395.     ret
  1396.  
  1397.     ; move name found to current name
  1398.     ;
  1399. mfn03:
  1400.     mov    SI,offset dta+1        ; place where MSDOS puts name
  1401.     push    SI            ; save name pointer
  1402.     mov    DI,offset mfcur+1
  1403.     mov    CX,11
  1404.     rep    movsb
  1405.  
  1406.     ; move name found to fcb
  1407.     ;
  1408.     pop    SI
  1409.     mov    DI,offset fcb+1
  1410.     mov    CX, 11
  1411.     rep    movsb
  1412.  
  1413.     ; setup fcb
  1414.     ;
  1415.     xor    AL,AL
  1416.     mov    byte ptr fcbext,AL
  1417.     mov    byte ptr fcbrno,AL
  1418.     mov    byte ptr mfflg1,AL    ; turn off 1st time sw
  1419.     ret
  1420.  
  1421.  
  1422.     ; test for $$$ filetype
  1423.     ;
  1424. TSTBAD:
  1425.     call    TESTIT            ;Check first one for $
  1426.     jz    TSTBAD1
  1427.     ret
  1428.  
  1429. TSTBAD1:
  1430.     call    TESTIT            ;Check second on
  1431.     jz    TESTIT
  1432.     ret
  1433.  
  1434. TESTIT:                    ;Fall through to test third
  1435.     mov    AL,byte ptr [BX]
  1436.     and    AL,07Fh
  1437.     cmp    AL,'$'
  1438.     lahf
  1439.     inc    BX
  1440.     sahf
  1441.     ret
  1442.  
  1443. ABEXT2:
  1444.     mov    AL,Byte Ptr FFLAG
  1445.     cmp    AL,'F'            ;Writing to file?
  1446.     jnz    ABEXT3            ;No
  1447. ABEXT2A:                ;Close incomplete file
  1448.     mov    AL,eof
  1449.     call    putcrcfile
  1450.     mov    AH,clostr        ; Close stream
  1451.     mov    BX,word ptr crcouth    ; CRCKLIST.$$$ stream number
  1452.     int    dos
  1453.     jnc    abext2C            ; continue if carry not set
  1454.     mov    AH,print        ; else, print error message
  1455.     mov    DX,offset abtext
  1456.     int    dos
  1457. ABEXT2C:
  1458.     mov    AH,deldir
  1459.     mov    DX,offset crcoutz
  1460.     int    dos
  1461. ABEXT3:
  1462.     mov    DX,offset ABORT
  1463. SIGNOFF:
  1464.     mov    AH,print
  1465.     int    dos
  1466.     mov    AL,Byte Ptr MATCHFLG
  1467.     or    AL,AL
  1468.     jz    EXIT
  1469.     xor    AL,AL
  1470.     mov    Byte Ptr FFLAG,AL
  1471.     call    CRLF
  1472.     mov    DX,offset CRCMATCH
  1473.     call    DISPLAY
  1474.     mov    AL,Byte Ptr MATCHNO
  1475.     call    DECIMAL
  1476.     mov    AL,Byte Ptr NOMATCH
  1477.     or    AL,AL
  1478.     jz    PARSE
  1479.     call    CRLF
  1480.     mov    DX,offset CRCNOMATCH
  1481.     call    DISPLAY
  1482.     mov    AL,Byte Ptr NOMATCH
  1483.     call    DECIMAL
  1484. PARSE:
  1485.     mov    AL,Byte Ptr FAILED
  1486.     or    AL,AL
  1487.     jz    NOTFOUND
  1488.     call    CRLF
  1489.     mov    DX,offset BADPARSE
  1490.     call    DISPLAY
  1491.     mov    AL,Byte Ptr FAILED
  1492.     call    DECIMAL
  1493. NOTFOUND:
  1494.     mov    AL,Byte Ptr FILES
  1495.     or    AL,AL
  1496.     jz    EXIT
  1497.     call    CRLF
  1498.     mov    DX,offset QTYNOFIND
  1499.     call    DISPLAY
  1500.     mov    AL,Byte Ptr FILES
  1501.     call    DECIMAL
  1502.  
  1503. ; exit, via system terminate process function
  1504. exit:    mov    AH, TrmProc        ; return to DOS
  1505.     int dos
  1506.  
  1507. ;
  1508. DECIMAL:
  1509.     mov    DL,0
  1510.     mov    CH,064H
  1511.     call    DEC1
  1512.     mov    CH,10
  1513.     call    DEC1
  1514.     add    AL,'0'
  1515.     jmp    TYPER
  1516. ;
  1517. DEC1:
  1518.     mov    CL,0FFH
  1519. DEC2:
  1520.     inc    CL
  1521.     sub    AL,CH
  1522.     jnb    DEC2
  1523.     add    AL,CH
  1524.     mov    DH,AL
  1525.     mov    AL,CL
  1526.     or    AL,DL
  1527.     jz    DEC3
  1528.     or    AL,'0'
  1529.     call    TYPER
  1530.     mov    DL,'0'
  1531. DEC3:
  1532.     mov    AL,DH
  1533.     ret
  1534.  
  1535. code    ENDS
  1536.  
  1537.  
  1538. ;    stack location
  1539. ;       --------------
  1540. ;
  1541. a_stack    SEGMENT PARA STACK
  1542.  
  1543.     db    100h dup (?)
  1544.  
  1545. a_stack    ENDS
  1546.  
  1547.  
  1548.     END    crck
  1549.